bitkeeper revision 1.1159.163.1 (418a492cLmf4ERioALCFwIiwi2Qh4g)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Thu, 4 Nov 2004 15:22:20 +0000 (15:22 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Thu, 4 Nov 2004 15:22:20 +0000 (15:22 +0000)
Fix idle loop to play nicely with RCU. Gets rid of annoying delays
during xenU boot. Also cleaned up the idle code in XenLinux.

.rootkeys
linux-2.6.9-xen-sparse/arch/xen/i386/kernel/process.c
linux-2.6.9-xen-sparse/arch/xen/i386/kernel/setup.c
linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile
linux-2.6.9-xen-sparse/arch/xen/kernel/process.c [deleted file]

index 4896a7d5e2451c736c61cca3565faa1238a94774..d9531369de934a18ef2265df5ae0a457c6945ed3 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c
 4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.9-xen-sparse/arch/xen/kernel/fixup.c
 412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.9-xen-sparse/arch/xen/kernel/gnttab.c
-40f56239sFcjHiIRmnObRIDF-zaeKQ linux-2.6.9-xen-sparse/arch/xen/kernel/process.c
 40f562392LBhwmOxVPsYdkYXMxI_ZQ linux-2.6.9-xen-sparse/arch/xen/kernel/reboot.c
 414c113396tK1HTVeUalm3u-1DF16g linux-2.6.9-xen-sparse/arch/xen/kernel/skbuff.c
 3f68905c5eiA-lBMQSvXLMWS1ikDEA linux-2.6.9-xen-sparse/arch/xen/kernel/xen_proc.c
index a278f8aa39c2b581deb7619a18fc19985e027826..1552e00db793e6e0147c9e6946a31ca54556c2d1 100644 (file)
@@ -86,50 +86,25 @@ void enable_hlt(void)
 
 EXPORT_SYMBOL(enable_hlt);
 
-/*
- * We use this if we don't have any better
- * idle routine..
- */
-void default_idle(void)
+/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */
+extern int set_timeout_timer(void);
+void xen_idle(void)
 {
-       if (!hlt_counter && current_cpu_data.hlt_works_ok) {
-               local_irq_disable();
-               if (!need_resched())
-                       safe_halt();
-               else
-                       local_irq_enable();
-       }
-}
+       int cpu = smp_processor_id();
 
-/*
- * On SMP it's slightly faster (but much more power-consuming!)
- * to poll the ->work.need_resched flag instead of waiting for the
- * cross-CPU IPI to arrive. Use this option with caution.
- */
-static void poll_idle (void)
-{
-       int oldval;
+       local_irq_disable();
 
-       local_irq_enable();
+       if (rcu_pending(cpu))
+               rcu_check_callbacks(cpu, 0);
 
-       /*
-        * Deal with another CPU just having chosen a thread to
-        * run here:
-        */
-       oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
-
-       if (!oldval) {
-               set_thread_flag(TIF_POLLING_NRFLAG);
-               asm volatile(
-                       "2:"
-                       "testl %0, %1;"
-                       "rep; nop;"
-                       "je 2b;"
-                       : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags));
-
-               clear_thread_flag(TIF_POLLING_NRFLAG);
+       if (need_resched()) {
+               local_irq_enable();
+       } else if (set_timeout_timer() == 0) {
+               /* NB. Blocking reenable events in a race-free manner. */
+               HYPERVISOR_block();
        } else {
-               set_need_resched();
+               local_irq_enable();
+               HYPERVISOR_yield();
        }
 }
 
@@ -144,82 +119,23 @@ void cpu_idle (void)
        /* endless idle loop with no priority at all */
        while (1) {
                while (!need_resched()) {
-                       void (*idle)(void);
                        /*
                         * Mark this as an RCU critical section so that
                         * synchronize_kernel() in the unload path waits
                         * for our completion.
                         */
                        rcu_read_lock();
-                       idle = pm_idle;
-
-                       if (!idle)
-                               idle = default_idle;
-
                        irq_stat[smp_processor_id()].idle_timestamp = jiffies;
-                       idle();
+                       xen_idle();
                        rcu_read_unlock();
                }
                schedule();
        }
 }
 
-/*
- * This uses new MONITOR/MWAIT instructions on P4 processors with PNI,
- * which can obviate IPI to trigger checking of need_resched.
- * We execute MONITOR against need_resched and enter optimized wait state
- * through MWAIT. Whenever someone changes need_resched, we would be woken
- * up from MWAIT (without an IPI).
- */
-static void mwait_idle(void)
-{
-       local_irq_enable();
-
-       if (!need_resched()) {
-               set_thread_flag(TIF_POLLING_NRFLAG);
-               do {
-                       __monitor((void *)&current_thread_info()->flags, 0, 0);
-                       if (need_resched())
-                               break;
-                       __mwait(0, 0);
-               } while (!need_resched());
-               clear_thread_flag(TIF_POLLING_NRFLAG);
-       }
-}
-
-void __init select_idle_routine(const struct cpuinfo_x86 *c)
-{
-       if (cpu_has(c, X86_FEATURE_MWAIT)) {
-               printk("monitor/mwait feature present.\n");
-               /*
-                * Skip, if setup has overridden idle.
-                * One CPU supports mwait => All CPUs supports mwait
-                */
-               if (!pm_idle) {
-                       printk("using mwait in idle threads.\n");
-                       pm_idle = mwait_idle;
-               }
-       }
-}
-
-static int __init idle_setup (char *str)
-{
-       if (!strncmp(str, "poll", 4)) {
-               printk("using polling idle threads.\n");
-               pm_idle = poll_idle;
-#ifdef CONFIG_X86_SMP
-               if (smp_num_siblings > 1)
-                       printk("WARNING: polling idle and HT enabled, performance may degrade.\n");
-#endif
-       } else if (!strncmp(str, "halt", 4)) {
-               printk("using halt in idle threads.\n");
-               pm_idle = default_idle;
-       }
-
-       return 1;
-}
-
-__setup("idle=", idle_setup);
+/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */
+/* Always use xen_idle() instead. */
+void __init select_idle_routine(const struct cpuinfo_x86 *c) {}
 
 void show_regs(struct pt_regs * regs)
 {
index 68a8f46b0953a247ffc9cefd97e4ca45d956089c..e10a0aaf9795bbad5502427f4837c0aac1a35621 100644 (file)
@@ -350,8 +350,6 @@ int nr_multicall_ents = 0;
 /* Raw start-of-day parameters from the hypervisor. */
 union xen_start_info_union xen_start_info_union;
 
-extern void (*pm_idle)(void);
-
 static void __init limit_regions(unsigned long long size)
 {
        unsigned long long current_addr = 0;
@@ -1324,8 +1322,6 @@ void __init setup_arch(char **cmdline_p)
        HYPERVISOR_vm_assist(VMASST_CMD_enable,
                             VMASST_TYPE_4gb_segments);
 
-       pm_idle = xen_cpu_idle;
-
        memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
        early_cpu_init();
 
index 3768ed261f2be4e4a67789749806544ee8490214..eef477fe3e6aaf32d451e1b715cad04a59a3ffd9 100644 (file)
@@ -9,5 +9,5 @@ $(obj)/vmlinux.lds:
 
 extra-y += vmlinux.lds
 
-obj-y  := ctrl_if.o evtchn.o fixup.o process.o reboot.o xen_proc.o empty.o \
+obj-y  := ctrl_if.o evtchn.o fixup.o reboot.o xen_proc.o empty.o \
            gnttab.o skbuff.o
diff --git a/linux-2.6.9-xen-sparse/arch/xen/kernel/process.c b/linux-2.6.9-xen-sparse/arch/xen/kernel/process.c
deleted file mode 100644 (file)
index 3a0c620..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-#include <stdarg.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/platform.h>
-#include <linux/pm.h>
-#include <linux/rcupdate.h>
-
-extern int set_timeout_timer(void);
-
-void xen_cpu_idle (void)
-{
-       struct rcu_data *rdp = &__get_cpu_var(rcu_bh_data);
-
-       local_irq_disable();
-       if (need_resched() || rdp->curlist) {
-               local_irq_enable();
-               return;
-       }
-       if (set_timeout_timer() == 0) {
-               /* NB. Blocking reenable events in a race-free manner. */
-               HYPERVISOR_block();
-               return;
-       }
-       local_irq_enable();
-       HYPERVISOR_yield();
-}